package com.swipemaster.elements;

import android.graphics.Bitmap;
import android.graphics.Canvas;

import com.swipemaster.common.Bitmaps;
import com.swipemaster.common.Const;
import com.swipemaster.common.Coords;
import com.swipemaster.common.Global;
import com.swipemaster.moves.Move;
import com.swipemaster.moves.PlayerMove;

public class Circle extends Element
{
	/** Radius of circle in px. */
	public final int radius;
	/** Scaled bitmaps used to draw this element. */
	protected final Bitmap primaryBitmap;
	protected final Bitmap secondaryBitmap;
	/** For eyes animation. */
	private boolean angry = true;
	/** Max 500 frames we won't change the state of eyes. When frame lasts 10ms it gives 5s of inactivity. */
	private final int EYES_TIMER_MAX = 500;
	/** Randomly choose how long to wait for eyes change. */
	private int eyesTimer = (int) (Math.random() * EYES_TIMER_MAX);

	/** @param x Center of the circle, x. Universal units.
	 * @param y Center of the circle, y. Universal units.
	 * @param move Strategy of move. */
	public Circle(double x, double y, Move move)
	{
		this(x, y, move, Const.RADIUS);
	}

	/** @param x Center of the circle, x. Universal units.
	 * @param y Center of the circle, y. Universal units.
	 * @param move Type of move.
	 * @param r Radius of the circle. Universal units. */
	public Circle(double x, double y, Move move, double r)
	{
		this(x, y, move, r, false);
	}

	/** @param x Center of the circle, x. Universal units.
	 * @param y Center of the circle, y. Universal units.
	 * @param move Type of move.
	 * @param r Radius of the circle. Universal units.
	 * @param transparent Whether element is transparent or not. */
	public Circle(double x, double y, Move move, double r, boolean transparent)
	{
		super(Coords.x(x), Coords.y(y), move, getMass(r));
		radius = (int) Coords.mulByDiag(r);

		final int width = 2 * radius;
		if (move instanceof PlayerMove)
		{
			primaryBitmap = Bitmaps.getScaledBitmap(width, width, Bitmaps.playerBitmap);
			secondaryBitmap = primaryBitmap;
		}
		else
		{
			if (transparent)
			{
				primaryBitmap = Bitmaps.getScaledBitmap(width, width, Bitmaps.alphaEnemyBitmap);
				secondaryBitmap = Bitmaps.getScaledBitmap(width, width, Bitmaps.alphaAngryEnemyBitmap);
			}
			else
			{
				primaryBitmap = Bitmaps.getScaledBitmap(width, width, Bitmaps.enemyBitmap);
				secondaryBitmap = Bitmaps.getScaledBitmap(width, width, Bitmaps.angryEnemyBitmap);
			}
		}
	}

	/** Simplified constructor for creation hordes of enemies.
	 * @param move Strategy of move. */
	public Circle(Move move)
	{
		this(move, Const.RADIUS);
	}

	/** @param move Strategy of move.
	 * @param radius Radius of the circle. Universal units. */
	public Circle(Move move, double radius)
	{
		this(0, 0, move, radius);
	}

	protected static double getMass(double radius)
	{
		return Math.PI * radius * radius;
	}

	/* This method must be very efficient since it will be called thousands of times. */
	@Override
	public void draw(Canvas canvas)
	{
		if (angry)
		{
			canvas.drawBitmap(secondaryBitmap, x - radius, y - radius, null);
		}
		else
		{
			canvas.drawBitmap(primaryBitmap, x - radius, y - radius, null);
		}

		eyesTimer++;
		if (eyesTimer > EYES_TIMER_MAX)
		{
			eyesTimer = (int) (Math.random() * EYES_TIMER_MAX);
			angry = !angry;
		}
	}

	@Override
	public boolean isCollisionWith(Element element)
	{
		if (element instanceof Circle)
		{
			final Circle circle = (Circle) element;
			return Collision.isCircleCircle(x, y, radius, circle.x, circle.y, circle.radius);
		}
		if (element instanceof Rectangle)
		{
			final Rectangle rect = (Rectangle) element;
			return Collision.isRectCircle(rect.x, rect.y, rect.width, rect.height, x, y, radius);
		}
		return false;
	}

	@Override
	public boolean isWallCollision(int wall, boolean wallCollision)
	{
		int tmpRadius;
		if (wallCollision)
		{
			tmpRadius = radius;
		}
		else
		{
			tmpRadius = -radius;
		}

		return ((wall == Const.LEFT) && ((x - tmpRadius) <= 1))
				|| ((wall == Const.RIGHT) && ((x + tmpRadius) >= (Global.app.consts.width - 1)))
				|| ((wall == Const.UP) && ((y - tmpRadius) <= 1))
				|| ((wall == Const.DOWN) && ((y + tmpRadius) >= (Global.app.consts.height - 1)));
	}
}